using System;
using System.Reflection;

using TrueCode.Core.Aspects;


namespace TrueCode.DependencyManager.Services.InjectionPoints
{
  [Serializable]
  public class TypedMethod : NamedMethod
  {
    private readonly Type[] _parameterTypes;

    public TypedMethod( [NotNull] string methodName, [NotNull] params Type[] parameterTypes )
      : this( methodName, 0, parameterTypes )
    {
    }

    public TypedMethod( [NotNull] string methodName, int executionOrder, [NotNull] params Type[] parameterTypes )
      : base( methodName, executionOrder )
    {
      if( parameterTypes == null ) throw new ArgumentNullException( "parameterTypes" );

      _parameterTypes = parameterTypes;
    }

    protected Type[] ParameterTypes
    {
      get { return _parameterTypes; }
    }

    public override MethodInfo GetMethod( Type type )
    {
      var methodInfo = type.GetMethod( MethodName, _parameterTypes );

      #region Assert that methodInfo has been got
      if( methodInfo == null )
      {
        var exc = new InvalidOperationException( "Type does not have specified method" );
        exc.Data.Add( "Type", type );
        exc.Data.Add( "Method", MethodName );
        throw exc;
      }
      #endregion

      return methodInfo;
    }
  }
}